﻿#include "grating.h"

#include "systemconfiguration.h"
#include "component_log.h"
#include "componentmanager.h"
#include "json_trans.h"

#define FAULT_TRIG ("0")
#define TRIG ("0")

Grating::Grating(QObject *parent)
	: ComponentBase(parent)
{
	m_name = "光栅管理组件";
	m_type = Component::component_grating;
}

Grating::~Grating()
{

}


// 组件初始化处理函数
int Grating::ComponentInit()
{
	auto cfg = syscfg->GetGratingSetting();
	if (cfg.isEmpty()) {
		log_error("未配置光栅，无需创建光栅组件");
		return COMMON_ERROR;
	}
	m_info.clear();
	for (auto& iter : cfg) {
		log_trace("光栅配置：id{}, trig{}, fault{}, enalbe:{}", iter.id, iter.trig, iter.fault, iter.enable);
		if (!iter.enable) {
			SetWarningmsg(QString("光栅[%1]未使能，无需加载").arg(iter.id));
			continue;
		}
		if (iter.id.isEmpty() || iter.fault <= 0 || iter.trig <= 0 || iter.fault > 32 || iter.trig > 32) {
			SetWarningmsg(QString("光栅[%1]配置错误，加载失败").arg(iter.id));
			continue;
		}
		GratingInfo info = {};
		info.abel = GratingEnableState::grating_state_enable;
		info.state = GratingState::grating_state_normal;
		info.id = iter.id;
		info.cfg.fault = iter.fault;
		info.cfg.tiger = iter.trig;
		m_info.insert(info.id, info);
		log_trace("光栅[{}]加载成功", info.id);
	}

	if (m_info.size() <= 0) {
		log_error("未配置光栅，无需创建光栅组件");
		return COMMON_ERROR;
	}

	auto rob = component->GetComponent(Component::component_robot);
	if (rob != nullptr) {
		QByteArray diInfo;
		rob->ExcuteCmd((int)RobotCmdType::robot_cmd_get_di, QString::number(-1).toUtf8(), diInfo);
		SetDIInfo(diInfo);
		rob->RegisterSubscriberFunction((int)RobotMsgType::robot_msg_DI, [&](const QByteArray& info) {
			return SetDIInfo(info);
			});
	} else {
		SetErrmsg("获取机械手组件出错，光栅组件初始化异常", false);
		return SERIOUS_ERROR;
	}

	return 0;
}
/*自检接口*/
bool Grating::ComponentCheckSelfState()
{
	for (auto& iter : m_info) {
		if (iter.abel != GratingEnableState::grating_state_enable) {
			SetErrmsg(QString("光栅[%1]处于运行通过状态").arg(iter.id));
			return false;
		}
		if (iter.state != GratingState::grating_state_normal) {
			if (iter.state == GratingState::grating_state_triger) {
				SetErrmsg(QString("光栅[%1]被阻挡").arg(iter.id));
				return false;
			} else if (iter.state == GratingState::grating_state_fault) {
				SetErrmsg(QString("光栅[%1]出现故障").arg(iter.id));
				return false;
			}
		}
	}

	return true;
}
/*复位接口*/
bool Grating::ComponentSelfReset()
{
	for (auto& iter : m_info) {
		if (iter.state != GratingState::grating_state_normal) {
			SetErrmsg(QString("光栅[%1]状态异常").arg(iter.id));
			return false;
		}

		iter.abel = GratingEnableState::grating_state_enable;
		log_trace("[{}] change to enable", iter.id);
	}

	return true;
}

void Grating::ResponseSystemState(int state)
{
	m_systemState = (SystemStateType)state;
}

// 命令执行接口
bool Grating::ExcuteCmd(int cmd, const QByteArray& input, QByteArray& output)
{
	GratingCmdType type = (GratingCmdType)cmd;
	switch (type) {
	case GratingCmdType::get_grating_trig_state:
		return GetGratingTrigState(input, output);
		break;
	case GratingCmdType::get_grating_able_state:
		return GetGratingAbleState(input, output);
		break;
	case GratingCmdType::set_grating_able_state:
		return SetGratingAbleState(input, output);
		break;
	case GratingCmdType::get_grating_id_list:
	{
		QStringList ids;
		for (auto& iter : m_info) {
			ids.append(iter.id);
		}
		output = ids.join(';').toUtf8();
		return true;
	}
		break;
	default:
		break;
	}
	output = "错误的命令类型";
	return false;
}

int Grating::SetDIInfo(const QString& info)
{
	for (auto& iter : m_info) {
		if (info.at(iter.cfg.fault - 1) == FAULT_TRIG) {
			if (iter.state != GratingState::grating_state_fault) {
				SetErrmsg(QString("光栅[%1]出现故障").arg(iter.id));
				iter.state = GratingState::grating_state_fault;
			}
			continue;
		}
		if (iter.abel == GratingEnableState::grating_state_enable) {
			if (info.at(iter.cfg.tiger - 1) == TRIG) {
				if (iter.state != GratingState::grating_state_triger) {
					SetErrmsg(QString("光栅[%1]被遮挡").arg(iter.id));
					iter.state = GratingState::grating_state_triger;
				}
			} else {
				if (iter.state != GratingState::grating_state_normal) {
					log_error("grating[{}] tiger jie chu", iter.id);
					iter.state = GratingState::grating_state_normal;
				}
			}
		}
	}

	return 0;
}

json_struct(AbleStateGet,
	mapping(QString, id);
prop(&id);
);

json_struct(AbleStateAns,
	mapping(QString, id);
mapping(QString, status);
prop(&id, &status);
);

bool Grating::GetGratingAbleState(const QByteArray& input, QByteArray& output)
{
	bool ret = false;
	AbleStateGet in = {};
	in.fromJson(input);
	AbleStateAns ans = {};
	ans.id = in.id();
	if (m_info.find(in.id()) == m_info.end()) {
		log_error("机械手未匹配到ID[{}]对应光栅", in.id());
		ans.status = "机械手未匹配到ID对应光栅";
		ret = false;
	} else {
		if (m_info[in.id()].abel == GratingEnableState::grating_state_disable) {
			ans.status = "disable";
		} else {
			ans.status = "enable";
		}
		ret = true;
	}
	output = ans.toByteArray();
	return ret;
}

json_struct(AbleStateSet,
	mapping(QString, id);
	mapping(QString, status);
	prop(&id, &status);
);
bool Grating::SetGratingAbleState(const QByteArray& input, QByteArray& output)
{
	bool ret = false;
	AbleStateSet in = {};
	in.fromJson(input);
	AbleStateAns ans = {};
	ans.id = in.id();
	if (m_info.find(in.id()) == m_info.end()) {
		log_error("机械手未匹配到ID[{}]对应光栅", in.id());
		ans.status = "机械手未匹配到ID对应光栅";
		ret = false;
	} else {
		if (in.status() == "disable") {
			QString msg;
			if (SetGratingDisable(in.id(), msg)) {
				ans.status = "disable";
				ret = true;
			} else {
				ans.status = msg;
				log_error("WCS Set grating[{}] to disable failed, error: {}", in.id(), msg);
				ret = false;
			}

		} else {
			m_info[in.id()].abel = GratingEnableState::grating_state_enable;
			log_trace("wcs Set grating[{}] to enable", in.id());
			ans.status = "enable";
			ret = true;
		}
	}

	output = ans.toByteArray();
	return ret;
}

bool Grating::SetGratingDisable(const QString& id, QString &msg)
{
	if (m_info.find(id) == m_info.end()) {
		msg = "未匹配到ID对应的光栅";
		return false;
	}

	if (m_systemState != SystemStateType::system_state_work) {
		msg = "机械手状态异常，无法将光栅设置为允许进入状态";
		return false;
	}
	auto& gra = m_info[id];
	if (gra.state == GratingState::grating_state_fault) {
		msg = "光栅故障，无法将光栅设置为允许进入状态";
		return false;
	} else if (gra.state == GratingState::grating_state_triger) {
		msg = "光栅已经被阻挡，无法将光栅设置为允许进入状态";
		return false;
	} else {
		gra.abel = GratingEnableState::grating_state_disable;
		msg = "设置完成";
		log_error("grating[{}] enable state change to diable", id);
	}
	return true;
}


bool Grating::GetGratingTrigState(const QByteArray& input, QByteArray& output)
{
	QString id = input;

	if (m_info.find(id) == m_info.end()) {
		output = "未匹配到ID对应的光栅";
		return false;
	}
	auto& gra = m_info[id];
	if (gra.abel == GratingEnableState::grating_state_disable) {
		output = "允许进入";
		return true;
	}

	if (gra.state == GratingState::grating_state_fault) {
		output = "故障状态";
	} else if (gra.state == GratingState::grating_state_triger) {
		output = "光栅阻挡状态";
	} else {
		output = "正常状态";
	}

	return true;
}
